//
//  BLIAPManager.m
//  BLIAPManager
//
//  Created by boundlessocean on 2018/10/14.
//

#import "BLIAPManager.h"
#import <CommonCrypto/CommonCrypto.h>
#import "SHIAPVerifyManger.h"

@interface BLIAPManager ()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
/** 检索产品请求 */
@property (nonatomic ,strong) SKProductsRequest *productRequest;
/** 所有内购产品 */
@property (nonatomic ,strong) NSArray<SKProduct *> *products;
/** 检索回调 */
@property(nonatomic,copy) void (^cheakComplete)(NSArray<SKProduct *> *, NSArray<NSString *> *, BLIAPError);
/** 交易请求 */
@property (nonatomic ,strong) SKMutablePayment *payment;
/** 未完成交易处理 */
@property(nonatomic,copy) void (^transactionsHandle)(NSMutableArray <BLIAPTransactionOrder *> *);
/** 与iTunes交易完成 */
@property(nonatomic,copy) void (^transactionComplete)(BLIAPTransactionOrder * ,BLIAPError );
/** 收据有效性查询队列. */
@property(nonatomic, strong) SHIAPVerifyManger *verifyManager;
@property (nonatomic, strong) NSString * sn;
@property (nonatomic, assign) BOOL isAutoBuy;

@end
@implementation BLIAPManager

+ (instancetype)shareIAPManager{
    static BLIAPManager *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[[self class] alloc] init];
    });
    return sharedInstance;
}



#pragma mark - - Public
- (void)logoutPaymentManager
{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}


- (void)configTransactionObserver:(BOOL)reLgoin
{
    if ([objectUserId length]) {
        
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        self.isAutoBuy = NO;
        if (reLgoin) {
            [self checkUnfinishedTransactionInKeyChain];
        }
        
        [[BLIAPManager shareIAPManager] handleUnfinishTransaction:^(NSMutableArray<BLIAPTransactionOrder *> *transactionOrder) {
              MyLog(@"得到的订单：%ld",transactionOrder.count);
              for (BLIAPTransactionOrder *order in transactionOrder) {
                  [[SHWebPlayPayTool sharedInstance]IAP_requestCheakReceipt:order];
              }
        }];
        

    }
}


- (void)checkUnfinishedTransactionInKeyChain
{
    // 未完成的列表.
    NSArray<SKPaymentTransaction *> *transactionsWaitingForVerifing = [[SKPaymentQueue defaultQueue] transactions];
    MyLog(@"沙河访问未完成订单%@",transactionsWaitingForVerifing);
    BLIAPError error = BLIAPErrorNone;
    for (SKPaymentTransaction *transaction in transactionsWaitingForVerifing) {
        // 购买没有交易标识和购买日期的, 是没有成功付款的, 直接 finish 掉.
        if (!transaction.transactionIdentifier || !transaction.transactionDate) {
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            continue;
        }
        
        [self transactionPurchased:transaction];
    }
    
    [self dealBlockMethod:error];

}



- (void)cheakProducts:(NSSet<NSString *> *)productIdentifiers
             complete:(void (^)(NSArray<SKProduct *> *,
                                NSArray<NSString *> *,
                                BLIAPError ))cheakComplete{
    _cheakComplete = cheakComplete;
    _productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    _productRequest.delegate = self;
    [_productRequest start];
}

- (void)requestPayment:(NSString *)sn
    productIdentifiers:(NSString *)productIdentifiers
              complete:(void (^)(BLIAPTransactionOrder * ,BLIAPError ))transactionComplete{
    _transactionsHandle = nil;
    _transactionComplete = transactionComplete;
    self.sn = sn;
    self.isAutoBuy = YES;
    
    // 未开启内购功能
    if (![SKPaymentQueue canMakePayments]) {
        !transactionComplete ? : transactionComplete(nil,BLIAPErrorCheakIAPState);
    } else {
    // 已开启内购功能
        SKProduct *productMacth;
        for (SKProduct *product in _products) {
            if ([product.productIdentifier isEqualToString:productIdentifiers]) {
                productMacth = product;
            }
        }
        // 匹配到产品
        if (productMacth) {
            _payment = [SKMutablePayment paymentWithProduct:productMacth];
            _payment.applicationUsername = sn;
            [[SKPaymentQueue defaultQueue] addPayment:_payment];
        } else {
        // 未匹配到产品
            !transactionComplete ? : transactionComplete(nil,BLIAPErrorUnableFindProduct);
        }
    }
}

- (void)handleUnfinishTransaction:(void (^)(NSMutableArray<BLIAPTransactionOrder *> *))transactionsHandle{
    _transactionsHandle = transactionsHandle;
}

- (void)cheakTransactionOrder:(NSString *)orderJson
                     complete:(void (^)(BLIAPTransactionOrder *, BLIAPError))complete{
    BLIAPError error = BLIAPErrorNone;
    for (SKPaymentTransaction *transaction in [SKPaymentQueue defaultQueue].transactions) {
        if ([transaction.payment.productIdentifier isEqualToString:orderJson]) {
            error = BLIAPErrorNone;
            if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
                !complete ? : complete([self initializeOrder:transaction],error);
                return;
            } else {
                error = BLIAPErrorTransactionStateUnpay;
            }
            break;
        } else {
            error = BLIAPErrorUnableFindProduct;
        }
    }
    !complete ? : complete(nil,error);
}
#pragma mark - 交易结束
- (void)finishTransactionOreder:(BLIAPTransactionOrder *)transactionOrder
{
    // 未完成的列表.
    NSArray<SKPaymentTransaction *> *transactionsWaitingForVerifing = [[SKPaymentQueue defaultQueue] transactions];
    MyLog(@"交易结束未完成的列表%ld",transactionsWaitingForVerifing.count);
    
     SKPaymentTransaction *targetTransaction = nil;
    for (SKPaymentTransaction *transaction in transactionsWaitingForVerifing) {
        // 购买没有交易标识和购买日期的, 是没有成功付款的, 直接 finish 掉.
        if (!transaction.transactionIdentifier || !transaction.transactionDate) {
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            continue;
        }
        
        if ([transactionOrder.transactionID isEqualToString:transaction.transactionIdentifier]) {
            targetTransaction = transaction;
            break;
        }
    }
    
    if (targetTransaction) {
        if ([self.verifyManager paymentDeleteWhenExisted:transactionOrder transaction:targetTransaction]) {
            MyLog(@"进入这里了后结束这笔订单");
             [[SKPaymentQueue defaultQueue] finishTransaction:targetTransaction];
        }
    }
    
}
/** 交易不全 */
- (void)finishTransactionOrderInChina:(BLIAPTransactionOrder *)transactionOrder
{
    // 未完成的列表.
    NSArray<SKPaymentTransaction *> *transactionsWaitingForVerifing = [[SKPaymentQueue defaultQueue] transactions];
    MyLog(@"交易结束未完成的列表%ld",transactionsWaitingForVerifing.count);

     SKPaymentTransaction *targetTransaction = nil;
    for (SKPaymentTransaction *transaction in transactionsWaitingForVerifing) {
        // 购买没有交易标识和购买日期的, 是没有成功付款的, 直接 finish 掉.
        if (!transaction.transactionIdentifier || !transaction.transactionDate) {
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            continue;
        }

        if ([transactionOrder.transactionID isEqualToString:transaction.transactionIdentifier]) {
            targetTransaction = transaction;
            break;
        }
    }

    if (targetTransaction) {
        [self.verifyManager paymentDeleteWhenExisted:transactionOrder transaction:targetTransaction];
    }
    
}


#pragma mark - - SKRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request
     didReceiveResponse:(SKProductsResponse *)response{
    _products = response.products;
    !_cheakComplete ? : _cheakComplete(response.products,
                                       response.invalidProductIdentifiers,
                                       BLIAPErrorNone);
}

- (void)request:(SKRequest *)request
didFailWithError:(NSError *)error{
    !_cheakComplete ? : _cheakComplete(nil,
                                       nil,
                                       BLIAPErrorUnableConnectiTunseStore);
}


#pragma mark - - SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue
 updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
//    NSMutableArray <BLIAPTransactionOrder *> *unFinishTransactions = [NSMutableArray arrayWithCapacity:0];
    MyLog(@"进入updatedTransactions");
    BLIAPError error = BLIAPErrorNone;
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState){
                MyLog(@"交易状态：：：%ld",transaction.transactionState)
            case SKPaymentTransactionStatePurchased:{
//                BLIAPTransactionOrder *order = [self initializeOrder:transaction];
//                [unFinishTransactions addObject:order];
                [self transactionPurchased:transaction];
            }
                break;
            case SKPaymentTransactionStateFailed:
            {
                error = BLIAPErrorTransactionStateFailed;
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }
                break;
            case SKPaymentTransactionStatePurchasing:
            case SKPaymentTransactionStateDeferred:
            case SKPaymentTransactionStateRestored:
                return;
        }
    }
    
    [self dealBlockMethod:error];
    
}

/** 相关的回调 */
- (void)dealBlockMethod:(BLIAPError)error
{
    NSMutableArray <BLIAPTransactionOrder *> *unFinishTransactions = [self.verifyManager fetchAllPayment];
    MyLog(@"未完成的订单：%ld",unFinishTransactions.count);
    if (_transactionsHandle && unFinishTransactions.count) {
        _transactionsHandle(unFinishTransactions);
    } else if (_transactionComplete){
        _transactionComplete(unFinishTransactions.firstObject,error);
    }
    
    //    if (_transactionsHandle && unFinishTransactions.count) {
    //        _transactionsHandle(unFinishTransactions);
    //    } else if (_transactionComplete){
    //        _transactionComplete(unFinishTransactions.firstObject,error);
    //    }
}



/** 获取当前登录用户的所有订单 */
- (NSArray *)showUserFinishOrder
{
    NSArray <BLIAPTransactionOrder *> *unFinishTransactions = [self.verifyManager fetchAllCountPayment];
    return unFinishTransactions;
}

#pragma mark - transactionState
/** 交易成功 */
- (void)transactionPurchased:(SKPaymentTransaction *)transaction
{
    //存储
//    [self.verifyManager delAllNotification];

    if (![self.verifyManager transactionDidStoreInKeyChainWithTransactionIdentifier:transaction.transactionIdentifier]) {
        MyLog(@"未存在，再次存储");
        BLIAPTransactionOrder *order = [self initializeOrder:transaction];
        [self.verifyManager appendPaymentTransactionModel:order];
    }
    

  
}


/** 配置订单 */
- (BLIAPTransactionOrder *)initializeOrder:(SKPaymentTransaction *)transaction{
    NSURL *rereceiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:rereceiptURL];
    BLIAPTransactionOrder *order = [self generateTransactionModelWithPaymentTransaction:transaction];
    if (!receiptData) {
        SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];
        request.delegate = self;
        [request start];
    } else {
        order.receiptData = [receiptData base64EncodedStringWithOptions:0];
    }
    return order;
//    BLIAPTransactionOrder *order = [BLIAPTransactionOrder new];
//    order.sn = transaction.payment.applicationUsername;
//    order.receiptData = [receiptData base64EncodedStringWithOptions:0];
//    order.productID = transaction.payment.productIdentifier;
//    order.transactionID = transaction.transactionIdentifier;
//    return order;
}

// 获取到对应的收据, 创建需验证模型, 持久化到需验证队列 ✅.
- (BLIAPTransactionOrder *)generateTransactionModelWithPaymentTransaction:(SKPaymentTransaction *)transaction
{
    BLIAPTransactionOrder *order = [[BLIAPTransactionOrder alloc] init];
      order.sn = transaction.payment.applicationUsername;
    if (!order.sn) {
        order.sn = self.sn;
    }
     MyLog(@"查看这个的sn值为：：：%@,,,%@,,,%@",order.sn,self.sn,transaction.payment.applicationUsername);
      order.productID = transaction.payment.productIdentifier;
      order.transactionID = transaction.transactionIdentifier;
    if (self.isAutoBuy) {
        order.uid = objectUserId;
    } else {
        order.uid = @"dtk";

    }
    return order;
}

#pragma mark - - Private

/** SHA-256 哈希 */
- (NSString *)hashedValueForAccountName:(NSString*)userAccountName{
    
    if (!userAccountName) {
        userAccountName = BLIAPManager.deviceUDID;
    }
    const int HASH_SIZE = 32;
    unsigned char hashedChars[HASH_SIZE];
    const char *accountName = [userAccountName UTF8String];
    size_t accountNameLen = strlen(accountName);
    if (accountNameLen > UINT32_MAX) {
        NSLog(@"Account name too long to hash: %@", userAccountName);
        return nil;
    }
    CC_SHA256(accountName, (CC_LONG)accountNameLen, hashedChars);
    NSMutableString *userAccountHash = [[NSMutableString alloc] init];
    for (int i = 0; i < HASH_SIZE; i++) {
        if (i != 0 && i%4 == 0) {
            [userAccountHash appendString:@"-"];
        }
        [userAccountHash appendFormat:@"%02x", hashedChars[i]];
    }
    return userAccountHash;
}


+ (NSString *)deviceUDID{
    NSString *deviceUDID = [[NSUbiquitousKeyValueStore defaultStore] objectForKey:[[NSBundle mainBundle].bundleIdentifier stringByAppendingString:@"deviceUDID"]];
    if (!deviceUDID) {
        deviceUDID = [UIDevice currentDevice].identifierForVendor.UUIDString;
        [[NSUbiquitousKeyValueStore defaultStore] setObject:deviceUDID forKey:[[NSBundle mainBundle].bundleIdentifier stringByAppendingString:@"deviceUDID"]];
        [[NSUbiquitousKeyValueStore defaultStore] synchronize];
    }
    return deviceUDID;
}


#pragma mark - Lazy
- (SHIAPVerifyManger *)verifyManager
{
    if (_verifyManager == nil) {
        _verifyManager = [[SHIAPVerifyManger alloc] init];
    }
    return _verifyManager;
}


@end


@implementation BLIAPTransactionOrder
//将BLIAPTransactionOrder归档处理，写上下句代码
MJExtensionCodingImplementation
@end
